﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;

using NUnit.Framework;

namespace Working.Domínio.Teste
{
    [TestFixture]
    public class TesteCardeiraDeIdentidade
    {
        [Test]
        public void TestarConstrutorComParâmetros()
        {
            Pessoa pessoa = new Pessoa("Fulano de Tal", DateTime.Today);
            string registroGeral = "MG-11.617.344";

            CarteiraDeIdentidade carteira = new CarteiraDeIdentidade(pessoa, registroGeral);

            Assert.AreEqual(registroGeral, carteira.RegistroGeral);
            Assert.AreEqual(DateTime.MinValue, carteira.DataDeExpedição);
            Assert.AreEqual(string.Empty, carteira.OrgãoEmissor);
            Assert.AreEqual(string.Empty, carteira.UnidadeFederativa);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestarConstrutorComParâmetrosInválido1()
        {
            Pessoa pessoa = new Pessoa("Fulano de Tal", DateTime.Today);
            string registroGeral = string.Empty;

            CarteiraDeIdentidade carteira = new CarteiraDeIdentidade(pessoa, registroGeral);

            Assert.AreEqual(registroGeral, carteira.RegistroGeral);
            Assert.AreEqual(DateTime.MinValue, carteira.DataDeExpedição);
            Assert.AreEqual(string.Empty, carteira.OrgãoEmissor);
            Assert.AreEqual(string.Empty, carteira.UnidadeFederativa);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestarConstrutorComParâmetrosInválido2()
        {
            Pessoa pessoa = null;
            string registroGeral = "MG-11.617.344";

            CarteiraDeIdentidade carteira = new CarteiraDeIdentidade(pessoa, registroGeral);

            Assert.AreEqual(registroGeral, carteira.RegistroGeral);
            Assert.AreEqual(DateTime.MinValue, carteira.DataDeExpedição);
            Assert.AreEqual(string.Empty, carteira.OrgãoEmissor);
            Assert.AreEqual(string.Empty, carteira.UnidadeFederativa);
        }


        [Test]
        public void TestarPropriedades()
        {
            string nome = "Guilherme Andrade Del Cantoni";
            string nomeDaMãe = "Valéria de Souza Andrade";
            string nomeDoPai = "Magno Del Cantoni";
            string naturalidade = "Belo Horizonte";
            string registroGeral = "MG-11.617.344";
            string orgãoEmissor = "SSP";
            string uf = "MG";
            DateTime dataDeNascimento = new DateTime(1984, 03, 11);
            DateTime dataDeExpedição = new DateTime(1984, 03, 11);

            Pessoa pessoa = new Pessoa(nome, dataDeNascimento);
            pessoa.NomeDaMãe = nomeDaMãe;
            pessoa.NomeDoPai = nomeDoPai;
            pessoa.Naturalidade = new Cidade(naturalidade);

            CarteiraDeIdentidade carteira = new CarteiraDeIdentidade(pessoa, registroGeral);
            carteira.OrgãoEmissor = orgãoEmissor;
            carteira.UnidadeFederativa = uf;
            carteira.DataDeExpedição = dataDeExpedição;

            Assert.AreEqual(registroGeral, carteira.RegistroGeral);
            Assert.AreEqual(dataDeExpedição, carteira.DataDeExpedição);
            Assert.AreEqual(orgãoEmissor, carteira.OrgãoEmissor);
            Assert.AreEqual(uf, carteira.UnidadeFederativa);
            Assert.AreEqual(nome, carteira.Nome);
            Assert.AreEqual(nomeDaMãe, carteira.NomeMãe);
            Assert.AreEqual(nomeDoPai, carteira.NomePai);
            Assert.AreEqual(naturalidade, carteira.Naturalidade);
        }

        [Test]
        public void TestarSerializaçãoBinária()
        {
            //Inicializa valores a serem comparados
            string nome = "Guilherme Andrade Del Cantoni";
            DateTime dataDeNascimento = new DateTime(1984, 03, 11);
            string nomeDaMãe = "Valéria de Souza Andrade";
            string nomeDoPai = "Magno Del Cantoni";
            Cidade naturalidade = new Cidade("Belo Horizonte");
            País nacionalidade = new País("Brasil");
            string registroGeral = "MG-11.617.344";
            string orgãoEmissor = "SSP";
            string unidadeFederativa = "MG";
            DateTime dataDeExpedição = new DateTime(1998, 01, 01);

            //Atribui valores a classe CarteiraDeIdentidade e outras relacionadas
            Pessoa pessoa = new Pessoa(nome, dataDeNascimento);
            pessoa.NomeDaMãe = nomeDaMãe;
            pessoa.NomeDoPai = nomeDoPai;
            pessoa.Naturalidade = naturalidade;
            pessoa.Nacionalidade = nacionalidade;
            Domínio.Instância.AdicionarEntidadeAoCache(pessoa);

            CarteiraDeIdentidade carteira = new CarteiraDeIdentidade(pessoa, registroGeral);
            carteira.OrgãoEmissor = orgãoEmissor;
            carteira.UnidadeFederativa = unidadeFederativa;
            carteira.DataDeExpedição = dataDeExpedição;

            //Serializa CarteiraDeIdentidade em memória
            Stream stream = new MemoryStream();
            try
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(stream, carteira);

                //Apaga referência a objetos verificados
                pessoa = null;
                carteira = null;
                stream.Position = 0;

                //Deserializa objeto CarteiraDeIdentidade
                CarteiraDeIdentidade novaCarteira = (CarteiraDeIdentidade)binaryFormatter.Deserialize(stream);

                //Verifica integridade o objeto
                Assert.AreEqual(nome, novaCarteira.Nome);
                Assert.AreEqual(dataDeNascimento, novaCarteira.DataDeNascimento);
                Assert.AreEqual(nomeDaMãe, novaCarteira.NomeMãe);
                Assert.AreEqual(nomeDoPai, novaCarteira.NomePai);
                Assert.AreEqual(naturalidade.ToString(), novaCarteira.Naturalidade);
                Assert.AreEqual(registroGeral, novaCarteira.RegistroGeral);
                Assert.AreEqual(orgãoEmissor, novaCarteira.OrgãoEmissor);
                Assert.AreEqual(dataDeExpedição, novaCarteira.DataDeExpedição);
                Assert.AreEqual(unidadeFederativa, novaCarteira.UnidadeFederativa);
            }
            finally
            {
                stream.Dispose();
            }                        
        }
    }
}
